package com.budwk.app.sqfwV2.service.weiqingmen;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.dfxyWechatMP.DfxyWeChatMPUtils;
import com.budwk.app.exception.ServiceException;
import com.budwk.app.sms.dto.SmsMsgDTO;
import com.budwk.app.sms.service.OpaSmsService;
import com.budwk.app.sms.service.ZtSmsService;
import com.budwk.app.sqfw.constants.CommonConstants;
import com.budwk.app.sqfw.constants.SqfwFormSummaryConstants;
import com.budwk.app.sqfw.dto.SqfwCompleteFlowUpdateDTO;
import com.budwk.app.sqfw.enums.SqfwFormSummaryFieldEnum;
import com.budwk.app.sqfw.enums.SupportBusinessTypeEnum;
import com.budwk.app.sqfw.models.Sqfw_Sms_Msg;
import com.budwk.app.sqfw.models.Sqfw_completeflow;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.models.Sqfw_form_summary_pdf;
import com.budwk.app.sqfw.services.SqfwCompleteflowService;
import com.budwk.app.sqfw.services.SqfwFormSummaryPdfService;
import com.budwk.app.sqfw.services.SqfwFormsummaryNewService;
import com.budwk.app.sqfw.services.SqfwSmsMsgService;
import com.budwk.app.sqfw.vo.GenerateWordAndPdfUrlVO;
import com.budwk.app.sqfwDoc.bo.ExcelCreateConfig;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.AbstractCustomerPdfCreateField;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.CompleteFlowPdfParamForController;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.PdfGenerateParam;
import com.budwk.app.sqfwDoc.codeGeneratorV2.generate.BasePdfGenerator;
import com.budwk.app.sqfwDoc.codeGeneratorV2.generate.ResultOfExcelGenerator;
import com.budwk.app.sqfwDoc.codeGeneratorV2.pdfService.CompleteFlowCommonPdfService;
import com.budwk.app.sqfwDoc.codeGeneratorV2.result.GeneratorPdfWordResult;
import com.budwk.app.sqfwDoc.dto.CompleteFlowTemplateCodeUpdateDTO;
import com.budwk.app.sqfwDoc.dto.TemplateCodeUpdateDTO;
import com.budwk.app.sqfwV2.component.SummarySafetyCommponent;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.DownExcelLedgerReqVo;
import com.budwk.app.sqfwV2.dto.entity.SqfwShopsBaseInfo;
import com.budwk.app.sqfwV2.dto.vo.SummaryQueryReqVo;
import com.budwk.app.sqfwV2.dto.weiqingmen.InterviewDTO;
import com.budwk.app.sqfwV2.dto.weiqingmen.SafetyCheckDTO;
import com.budwk.app.sqfwV2.enums.weiqingmen.SafetyCheckEnum;
import com.budwk.app.sqfwV2.generator.weiqingmen.*;
import com.budwk.app.sqfwV2.service.ShopsBaseInfoService;
import com.budwk.app.sqfwV2.service.SummarySafetyService;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.util.StrUtil;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.budwk.starter.common.page.Pagination;
import com.budwk.starter.common.result.Result;
import com.budwk.starter.security.utils.SecurityUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Record;
import org.nutz.dao.sql.Criteria;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.budwk.app.util.poiUtils.CommonFormOfficeUtils.generateWordDocument;

/**
 * @author 东方祥云低代码1.1
 * @since 2024-04-01
 * <p>
 * 威清门消防安全排查 SafetyCheck
 */
@IocBean
@Slf4j
public class SafetyCheckPdfService extends CompleteFlowCommonPdfService {

    @Inject
    SysUserService sysUserService;
    @Inject
    OpaSmsService opaSmsService;
    @Inject
    SqfwSmsMsgService sqfwSmsMsgService;
    @Inject
    SqfwFormSummaryPdfService sqfwFormSummaryPdfService;
    @Inject
    SqfwFormsummaryNewService sqfwFormsummaryNewService;
    @Inject
    SqfwCompleteflowService sqfwCompleteflowService;
    @Inject
    TrafficEmergencyInspectionPdfService trafficEmergencyInspectionPdfService;
    @Inject
    ThreeInOneInspectionPdfService threeInOneInspectionPdfService;
    @Inject
    BottledGasUserSafetyManagementPdfService bottledGasUserSafetyManagementPdfService;
    @Inject
    KeyPlacePdfService keyPlacePdfService;
    @Inject
    FireSafetyInCateringEstablishmentsPdfService fireSafetyInCateringEstablishmentsPdfService;
    @Inject
    EmergencyInspectionPdfService emergencyInspectionPdfService;
    @Inject
    ShopsBaseInfoService shopsBaseInfoService;
    @Inject
    private ZtSmsService ztSmsService;
    @Inject
    private SummarySafetyCommponent summarySafetyCommponent;
    @Inject
    private SummarySafetyService summarySafetyService;

    /**
     * 创建pdf 2.0版本
     *
     * @param dto
     */
    public void submitData(TemplateCodeUpdateDTO dto) {
        log.info("威清门安全排查：{}", JSONUtil.toJsonStr(dto));
        CompleteFlowPdfParamForController paramForController = new CompleteFlowPdfParamForController();
        CompleteFlowTemplateCodeUpdateDTO completeFlowDataDTO = new CompleteFlowTemplateCodeUpdateDTO();
        completeFlowDataDTO.setFormSummary(dto.getFormSummary());
        completeFlowDataDTO.setCompleteFlow(dto.getCompleteFlow());
        paramForController.setCompleteFlowDataDTO(completeFlowDataDTO);
        paramForController.setUserId(SecurityUtil.getUserId());

        // 更新店铺状态
        SqfwShopsBaseInfo shopsBaseInfo = shopsBaseInfoService.fetch(dto.getFormSummary().getShopsBaseInfoId());
        shopsBaseInfo.setShopStatus(SqfwFormSummaryFieldEnum.check_status_checked.getCode());
        shopsBaseInfoService.updateIgnoreNull(shopsBaseInfo);

        // 创建任务
        summarySafetyCommponent.createOneTask(dto, null, getSummaryType());
        // 创建pdf
        super.createPdfAndMsg(paramForController);
    }

    /**
     * pdf合集下载（通过sqfwIdList下载pdf合集）2.0版本
     *
     * @param reqVo
     * @return
     */
    public List<ResultOfExcelGenerator> downPdfList(DownExcelLedgerReqVo reqVo) {
        List<ExcelCreateConfig> excelConfigList = new ArrayList<>();
        if (reqVo.isDownTemplate()) {
            ExcelCreateConfig config = new ExcelCreateConfig();
            config.setFileIdentity(reqVo.getFileCode());
            config.setOnlyGenerateTemplateFlag(true);
            excelConfigList.add(config);
        } else {
            Map<String,Object> param = new HashMap<>();
            param.put("start", reqVo.getFillStartDate());
            param.put("end", reqVo.getFillEndDate());
            param.put("shopInfoId", reqVo.getShopInfoId());
            if (reqVo.isCheckData()) {
                List<SafetyCheckEnum> safetyCheckEnumList = SafetyCheckEnum.getPdf();
                safetyCheckEnumList.sort(Comparator.comparing(SafetyCheckEnum::getOrder)); // 升序
                for (SafetyCheckEnum pdf : safetyCheckEnumList) {
                    ExcelCreateConfig config = new ExcelCreateConfig();
                    config.setFileIdentity(pdf.getCode());
                    config.setCreateExcelFileFlag(false);
                    config.setParam(param);
                    excelConfigList.add(config);
                }
            } else {
                ExcelCreateConfig config = new ExcelCreateConfig();
                config.setFileIdentity(reqVo.getFileCode());
                config.setCreateExcelFileFlag(true);
                config.setParam(param);
                excelConfigList.add(config);
            }
        }
        return downPdfList(excelConfigList, null);
    }

    /**
     * 获取列表数据 2.0版本
     * @return
     */
    public Result<?> list(Integer pageNo, Integer pageSize, String fillDate, String sort) {
        SummaryQueryReqVo dto = new SummaryQueryReqVo();
        dto.setPageNo(pageNo);
        dto.setPageSize(pageSize);
        dto.setSort(sort);
        dto.setFillDate(fillDate);
        dto.setFillType(getSummaryType());
        return summarySafetyService.listSummaryByPage(dto);
    }

    /**
     * 获取店铺最新一条巡查记录 2.0版本
     * @return
     */
    public Sqfw_formSummary_new getFormSummaryByShopId(String shopId) {
        Cnd cnd = Cnd.NEW();
        cnd.and(Sqfw_formSummary_new::getType, "=", getSummaryType());
        cnd.and(Sqfw_formSummary_new::getShopsBaseInfoId, "=", shopId);
        cnd.desc(Sqfw_formSummary_new::getFillDate);
        return summarySafetyService.fetch(cnd);
    }

    /**
     * 更新 2.0版本
     * @param dto
     */
    public void update(TemplateCodeUpdateDTO dto) {
        log.info("威清门安全排查更新：{}", JSONUtil.toJsonStr(dto));

        sqfwFormsummaryNewService.updateIgnoreNull(dto.getFormSummary());
        Sqfw_formSummary_new formSummaryNew = sqfwFormsummaryNewService.fetch(dto.getFormSummary().getId());
        CompleteFlowPdfParamForController paramForController = new CompleteFlowPdfParamForController();
        CompleteFlowTemplateCodeUpdateDTO updateDTO = new CompleteFlowTemplateCodeUpdateDTO();
        updateDTO.setFormSummary(formSummaryNew);
        paramForController.setCompleteFlowDataDTO(updateDTO);
        paramForController.setCompleteFlowId(formSummaryNew.getSqfwFlowId());
        paramForController.setUserId(SecurityUtil.getUserId());
        super.reCreatePdfAndMsg(paramForController);
    }


    /**
     * 创建pdf
     *
     * @param dto
     */
    public void createPdfAndMsg(CompleteFlowTemplateCodeUpdateDTO dto) {
        CompleteFlowPdfParamForController paramForController = new CompleteFlowPdfParamForController();
        paramForController.setCompleteFlowDataDTO(dto);
        paramForController.setUserId(SecurityUtil.getUserId());
        super.createPdfAndMsg(paramForController);
    }

    /**
     * 根据completeFlowId重新生成pdf
     *
     * @param completeFlowId
     */
    public void reCreatePdfAndMsg(String completeFlowId) {
        CompleteFlowPdfParamForController paramForController = new CompleteFlowPdfParamForController();
        Cnd cnd = Cnd.NEW();
        cnd.and(Sqfw_formSummary_new::getSqfwFlowId, "=", completeFlowId);
        Sqfw_formSummary_new formSummaryNew = sqfwFormsummaryNewService.fetch(cnd);
        if (formSummaryNew == null) {
            throw new RuntimeException("数据不存在");
        }
        paramForController.setUserId(formSummaryNew.getCreateBy());
        paramForController.setCompleteFlowId(completeFlowId);
        super.reCreatePdfAndMsg(paramForController);
    }

    /**
     * pdf合集下载（通过表：sqfw_form_summary_new 的 id 下载pdf合集）
     *
     * @param excelConfigList
     * @param summaryIds
     * @return
     */
    public List<ResultOfExcelGenerator> downPdfListToSummaryIds(List<ExcelCreateConfig> excelConfigList, List<String> summaryIds) {
        if (summaryIds == null || summaryIds.size() == 0) throw new ServiceException("请选择需要下载的数据");

        List<ResultOfExcelGenerator> generateExcelUrlVOS = new ArrayList<>();

        String sql = "select sc.resource_path from shequ.sqfw_completeflow sc left join shequ.sqfw_form_summary_new sfsn " +
                "on sc.id = sfsn.sqfw_flow_id where " +
                "sfsn.id in" + StrUtil.formatIds(summaryIds) +
                "and sc.resource_path != 'error' and sc.resource_path != 'creating' ";
        sql += "order by fill_date asc";
        List<Sqfw_completeflow> completeFlowList = sqfwCompleteflowService.listEntity(Sqls.create(sql));

        Cnd cnd = Cnd.NEW();
        cnd.and(Sqfw_form_summary_pdf::getStatus, "=", "2");
        cnd.and(Sqfw_form_summary_pdf::getSummaryId, "in", summaryIds);
        cnd.asc(Sqfw_form_summary_pdf::getCreateDate);
        List<Sqfw_form_summary_pdf> summaryPdfList = sqfwFormSummaryPdfService.query(cnd);

        for (ExcelCreateConfig config : excelConfigList) {

            // 模板下载
            if (config.getOnlyGenerateTemplateFlag()) {
                ResultOfExcelGenerator generateExcelUrlVO = new ResultOfExcelGenerator();
                String url = downWordTemplate(config);
                generateExcelUrlVO.setExcelUrl(url);
                generateExcelUrlVOS.add(generateExcelUrlVO);
                continue;
            }

            // 下载sqfw_form_summary_pdf
            if (!SafetyCheckEnum.SAFETY_INVESTIGATE_RENOVATE.getCode().equals(config.getFileIdentity())) {
                ResultOfExcelGenerator generateExcelUrlVO = downSummaryPdfList(config, summaryPdfList);
                generateExcelUrlVOS.add(generateExcelUrlVO);
                continue;
            }

            ResultOfExcelGenerator generateExcelUrlVO = new ResultOfExcelGenerator();
            generateExcelUrlVO.setFileIdentity(config.getFileIdentity());

            if (completeFlowList != null && completeFlowList.size() > 0) {
                generateExcelUrlVO.setPassCreateConditionFlag(true);
            } else {
                generateExcelUrlVO.setPassCreateConditionFlag(false);
            }

            // 数据检测
            if (!config.getCreateExcelFileFlag() || completeFlowList == null || completeFlowList.size() == 0) {
                generateExcelUrlVOS.add(generateExcelUrlVO);
                continue;
            }

            // 下载 安全排查整治表pdf
            List<String> pdfList = completeFlowList.stream().map(Sqfw_completeflow::getResourcePath).collect(Collectors.toList());
            try {
                String fileName = SafetyCheckEnum.getCompilationName(config.getFileIdentity());
                fileName = StrFormatter.format("{}-{}", fileName, DateUtil.format(new Date(), "yyyyMMdd"));
                String url = CommonFormOfficeUtils.createConvergePdf(pdfList, fileName);
                url = (url.startsWith("/")) ? NutzIocUtils.getOssPrefix() + url : url;
                generateExcelUrlVO.setExcelUrl(url);
            } catch (Exception e) {
                e.printStackTrace();
            }
            generateExcelUrlVOS.add(generateExcelUrlVO);
        }

        return generateExcelUrlVOS;
    }

    /**
     * pdf合集下载（通过sqfwIdList下载pdf合集）
     *
     * @param excelConfigList
     * @param sqfwIdList
     * @return
     */
    public List<ResultOfExcelGenerator> downPdfList(List<ExcelCreateConfig> excelConfigList, List<String> sqfwIdList) {

        List<ResultOfExcelGenerator> generateExcelUrlVOS = new ArrayList<>();
        String sql;
        ExcelCreateConfig config0 = excelConfigList.get(0);
        if (sqfwIdList != null && sqfwIdList.size() > 0) {
            sql = "select sc.resource_path, sfsn.id as id from shequ.sqfw_completeflow sc left join shequ.sqfw_form_summary_new sfsn " +
                    "on sc.id = sfsn.sqfw_flow_id where " +
                    "sc.sqfw_id in" + StrUtil.formatIds(sqfwIdList) +
                    "and sc.resource_path != 'error' and sc.resource_path != 'creating' ";
        } else {
            sql = "select sc.resource_path, sfsn.id as id from shequ.sqfw_completeflow sc left join shequ.sqfw_form_summary_new sfsn " +
                    "on sc.id = sfsn.sqfw_flow_id where " +
                    "sfsn.create_by ='" + SecurityUtil.getUserId() + "' and sfsn.type = '" + this.getSummaryType() +
                    "' and sc.resource_path != 'error' and sc.resource_path != 'creating' ";
            if (config0.getParam().get("start") != null && StringUtils.isNotBlank(config0.getParam().get("start").toString())) {
                sql += " and fill_date >= '" + config0.getParam().get("start").toString() + "'";
            }
            if (config0.getParam().get("end") != null && StringUtils.isNotBlank(config0.getParam().get("end").toString())) {
                sql += " and fill_date <= '" + config0.getParam().get("end").toString() + " 23:59:59'";
            }
            if (config0.getParam().get("shopInfoId") != null && StringUtils.isNotBlank(config0.getParam().get("shopInfoId").toString())) {
                sql += " and shops_base_info_id = '" + config0.getParam().get("shopInfoId").toString() + "'";
            }
        }
        sql += "order by fill_date asc";
        List<Sqfw_completeflow> completeFlowList = sqfwCompleteflowService.listEntity(Sqls.create(sql));

        // 此时Sqfw_completeflow的id存储的值实际是sqfw_form_summary_new的id，因为查询的时候我把sqfw_form_summary_new的id赋给了Sqfw_completeflow的id
        List<String> ids = completeFlowList.stream().map(Sqfw_completeflow::getId).collect(Collectors.toList());
        List<Sqfw_form_summary_pdf> summaryPdfList = new ArrayList<>();
        if (ids != null && ids.size() > 0) {
            Cnd cnd = Cnd.NEW();
            cnd.and(Sqfw_form_summary_pdf::getStatus, "=", "2");
            cnd.and(Sqfw_form_summary_pdf::getSummaryId, "in", ids);
            cnd.asc(Sqfw_form_summary_pdf::getCreateDate);
            summaryPdfList = sqfwFormSummaryPdfService.query(cnd);
        }

        for (ExcelCreateConfig config : excelConfigList) {

            // 模板下载
            if (config.getOnlyGenerateTemplateFlag()) {
                ResultOfExcelGenerator generateExcelUrlVO = new ResultOfExcelGenerator();
                String url = downWordTemplate(config);
                generateExcelUrlVO.setExcelUrl(url);
                generateExcelUrlVOS.add(generateExcelUrlVO);
                continue;
            }

            // 下载sqfw_form_summary_pdf
            if (!SafetyCheckEnum.SAFETY_INVESTIGATE_RENOVATE.getCode().equals(config.getFileIdentity())) {
                ResultOfExcelGenerator generateExcelUrlVO = downSummaryPdfList(config, summaryPdfList);
                generateExcelUrlVOS.add(generateExcelUrlVO);
                continue;
            }

            ResultOfExcelGenerator generateExcelUrlVO = new ResultOfExcelGenerator();
            generateExcelUrlVO.setFileIdentity(config.getFileIdentity());

            if (completeFlowList != null && completeFlowList.size() > 0) {
                generateExcelUrlVO.setPassCreateConditionFlag(true);
            } else {
                generateExcelUrlVO.setPassCreateConditionFlag(false);
            }

            // 数据检测
            if (!config.getCreateExcelFileFlag() || completeFlowList == null || completeFlowList.size() == 0) {
                generateExcelUrlVOS.add(generateExcelUrlVO);
                continue;
            }

            List<String> pdfList = completeFlowList.stream().map(Sqfw_completeflow::getResourcePath).collect(Collectors.toList());

            // 下载 安全排查整治表pdf
            try {
                String fileName = SafetyCheckEnum.getCompilationName(config.getFileIdentity());
                fileName = StrFormatter.format("{}-{}", fileName, DateUtil.format(new Date(), "yyyyMMdd"));
                String url = CommonFormOfficeUtils.createConvergePdf(pdfList, fileName);
                url = (url.startsWith("/")) ? NutzIocUtils.getOssPrefix() + url : url;
                generateExcelUrlVO.setExcelUrl(url);
            } catch (Exception e) {
                e.printStackTrace();
            }
            generateExcelUrlVOS.add(generateExcelUrlVO);
        }

        return generateExcelUrlVOS;
    }

    /**
     * 下载word模板
     *
     * @param config
     * @return
     */
    private String downWordTemplate(ExcelCreateConfig config) {
        String fileName = SafetyCheckEnum.getTemplateName(config.getFileIdentity());

        List<NiceXWPFDocument> xwpfDocumentList = new ArrayList<>();

        // 安全排查整治表模板
        if (SafetyCheckEnum.SAFETY_INVESTIGATE_RENOVATE.getCode().equals(config.getFileIdentity())) {
            // 威清门街道办事处应急巡查台账（餐饮店面）
            xwpfDocumentList.add(getNiceXWPFDocument(new CateringStorePdfGenerator().getTemplatePath(null)));
            // 威清门街道办事处应急巡查台账（店面）
            xwpfDocumentList.add(getNiceXWPFDocument(new StorefrontPdfGenerator().getTemplatePath(null)));
            // 威清门街道办事处应急巡查台账（临摊夜市摊）
            xwpfDocumentList.add(getNiceXWPFDocument(new NightMarketStallPdfGenerator().getTemplatePath(null)));
            // 威清门街道办事处应急巡查台账（工地装修）
            xwpfDocumentList.add(getNiceXWPFDocument(new SiteDecorationPdfGenerator().getTemplatePath(null)));
            // 威清门街道办事处应急巡查台账（危房）
            xwpfDocumentList.add(getNiceXWPFDocument(new DangerousBuildingPdfGenerator().getTemplatePath(null)));
            // 威清门街道办事处应急巡查台账（单位物管）
            xwpfDocumentList.add(getNiceXWPFDocument(new UnitPropertyManagementPdfGenerator().getTemplatePath(null)));
            // 威清门街道办事处应急巡查台账（重点场所）
            xwpfDocumentList.add(getNiceXWPFDocument(new KeyPlacePdfGenerator().getTemplatePath(null)));
            // 威清门街道办事处三合一应急巡查台账(三合一)
            xwpfDocumentList.add(getNiceXWPFDocument(new ThreeAndOnePdfGenerator().getTemplatePath(null)));
            // 威清门街道办事处交通应急巡查台账（快递）
            xwpfDocumentList.add(getNiceXWPFDocument(new ExpressPdfGenerator().getTemplatePath(null)));
            // 餐饮经营服务场所消防安全巡查台账
            xwpfDocumentList.add(getNiceXWPFDocument(new CateringServicePdfGenerator().getTemplatePath(null)));
            // 瓶装燃气用户安全管理检查表
            xwpfDocumentList.add(getNiceXWPFDocument(new BottledGasPdfGenerator().getTemplatePath(null)));
            // 安全生产整改通知书
            xwpfDocumentList.add(getNiceXWPFDocument(new SafeProductionPdfGenerator().getTemplatePath(null)));

            GenerateWordAndPdfUrlVO vo = CommonFormOfficeUtils.wordTemplateUpload(xwpfDocumentList, fileName);
            return vo.getWordUrl();
        }
        if (SafetyCheckEnum.TRAFFIC_EMERGENCY_INSPECTION.getCode().equals(config.getFileIdentity())) {
            return trafficEmergencyInspectionPdfService.downWordTemplate(config);
        }
        if (SafetyCheckEnum.BOTTLED_GAS_USER_SAFETY_MANAGEMENT.getCode().equals(config.getFileIdentity())) {
            return bottledGasUserSafetyManagementPdfService.downWordTemplate(config);
        }
        if (SafetyCheckEnum.FIRE_SAFETY_IN_CATERING_ESTABLISHMENTS.getCode().equals(config.getFileIdentity())) {
            return fireSafetyInCateringEstablishmentsPdfService.downWordTemplate(config);
        }
        if (SafetyCheckEnum.EMERGENCY_INSPECTION.getCode().equals(config.getFileIdentity())) {
            return emergencyInspectionPdfService.downWordTemplate(config);
        }
        if (SafetyCheckEnum.THREE_IN_ONE_INSPECTION.getCode().equals(config.getFileIdentity())) {
            return threeInOneInspectionPdfService.downWordTemplate(config);
        }
        if (SafetyCheckEnum.KEY_PLACE.getCode().equals(config.getFileIdentity())) {
            return keyPlacePdfService.downWordTemplate(config);
        }

        return null;
    }

    /**
     * 生成单个word
     *
     * @param templateName
     * @return
     */
    public NiceXWPFDocument getNiceXWPFDocument(String templateName) {
        Sys_user user = sysUserService.getUserById(SecurityUtil.getUserId());

        // 获取模板里 文本编辑、图片标签、表达式标签
        Map<String, Object> dataMap = CommonFormOfficeUtils.getWordTag(templateName);

        // 消防15个问题(数组标签只能自定义)
        List<String> arrayOfFireSafetyPatrolRecords = new ArrayList<>();
        for (int i = 0; i < 15; i++) {
            arrayOfFireSafetyPatrolRecords.add("");
        }
        dataMap.put("arrayOfFireSafetyPatrolRecords", arrayOfFireSafetyPatrolRecords);

        // 瓶装液化气27个问题(数组标签只能自定义)
        List<String> bottledGasProblemArray = new ArrayList<>();
        for (int i = 0; i < 27; i++) {
            bottledGasProblemArray.add("");
        }
        dataMap.put("bottledGasProblemArray", bottledGasProblemArray);

        XWPFTemplate xwpfTemplate = generateWordDocument(dataMap, BaseGenerator.getFooter(user), templateName);
        return xwpfTemplate.getXWPFDocument();
    }

    /**
     * 获取回显列表（去重, 'row_number() over' PostgreSQL分组函数）
     *
     * @param name
     * @return
     */
    public List<Record> echo(String name, String address) {
        if (StringUtils.isBlank(name) && StringUtils.isBlank(address)) return new ArrayList<>();

        String userId = SecurityUtil.getUserId();
        Sys_user user = sysUserService.fetch(userId);

        Cnd cnd = Cnd.NEW();
        cnd.and(Sqfw_formSummary_new::getProvince, "=", user.getProvince());
        cnd.and(Sqfw_formSummary_new::getCity, "=", user.getCity());
        cnd.and(Sqfw_formSummary_new::getDistrict, "=", user.getDistrict());
        cnd.and(Sqfw_formSummary_new::getCounty, "=", user.getCounty());
        cnd.and(Sqfw_formSummary_new::getCommunity, "=", user.getCommunity());
        String field = null;
        if (StringUtils.isNotBlank(name)) {
            field = "param_data->>'placeName'";
            cnd.and("param_data->>'placeName'", "like", "%" + name + "%");
        }
        // 只有危房按地址来查询
        if (StringUtils.isNotBlank(address)) {
            field = "param_data->>'address'";
            cnd.and("param_data->>'attributesOfInspectionUnits'", "=", "危房");
            cnd.and("param_data->>'address'", "like", "%" + address + "%");
        }

        String sql = "select * from (select id, param_data->>'placeName' as name, param_data->>'address' as address,fill_date as time," +
                "row_number() over (partition by " + field + " order by fill_date desc) " +
                "from shequ.sqfw_form_summary_new" + cnd + ") t where t.row_number = 1 limit 20";

        List<Record> records = sqfwFormsummaryNewService.list(Sqls.create(sql));

        if (StringUtils.isNotBlank(address)) {
            for (Record record : records) {
                record.set("name", record.get("address"));
            }
        }

        return records;
    }

    @Override
    public GeneratorPdfWordResult createPdfSync(CompleteFlowPdfParamForController paramForController) {
        return super.createPdfSync(paramForController);
    }

    /**
     * 获取用户自定义字段 代码生成器已经自动填充
     * 无需特殊修改
     *
     * @param paramData json字符串
     * @return 结果
     */
    @Override
    protected AbstractCustomerPdfCreateField getCustomerPdfField(String paramData) {
        return JSONObject.parseObject(paramData, SafetyCheckDTO.class);
    }

    /**
     * 允许用户自定义填充在创建pdf时所提供的数据
     *
     * @param pdfGenerateParam 创建pdf所提供的数据
     */
    @Override
    protected void customerPopularPdfGenerateParam(PdfGenerateParam pdfGenerateParam) {
        SafetyCheckDTO dto = (SafetyCheckDTO) pdfGenerateParam.getAbstractCustomerPdfCreateField();
        if ("危房".equals(dto.getAttributesOfInspectionUnits())) {
            Map<String, Object> customerParamMap = new HashMap<>();
            customerParamMap.put("lastFormSummary", null);
            pdfGenerateParam.setCustomerParamMap(customerParamMap);
            return;
        }
        Cnd cnd = Cnd.NEW();
        cnd.and("param_data->>'attributesOfInspectionUnits'", "=", dto.getAttributesOfInspectionUnits());
        cnd.and("param_data->>'placeName'", "=", dto.getPlaceName());
        cnd.and("param_data->>'address'", "=", dto.getAddress());
        cnd.and("(param_data->>'inspectionDate')::int8", "<", dto.getInspectionDate().getTime());
        cnd.orderBy("param_data->>'inspectionDate'", "desc");
        Sqfw_formSummary_new lastFormSummary = sqfwFormsummaryNewService.fetch(cnd);
        Map<String, Object> customerParamMap = new HashMap<>();
        customerParamMap.put("lastFormSummary", lastFormSummary);
        if (lastFormSummary != null) {
            Sys_user user = sysUserService.fetch(lastFormSummary.getCreateBy());
            customerParamMap.put("createUserName", user.getUsername());
            customerParamMap.put("lastSignatureUrl", user.getSignatureUrl());
        }
        pdfGenerateParam.setCustomerParamMap(customerParamMap);
    }

    /**
     * 在这里设置生成pdf的所有generator
     *
     * @param pdfGenerateParam 创建pdf的参数
     * @return 生成pdf的generator合集
     */
    @Override
    protected List<BasePdfGenerator> getPdfGenerator(PdfGenerateParam pdfGenerateParam) {
        SafetyCheckDTO fieldDTO = (SafetyCheckDTO) pdfGenerateParam.getAbstractCustomerPdfCreateField();
        List<BasePdfGenerator> generatorList = Lists.newArrayList();

        // 威清门街道办事处应急巡查台账（餐饮店面）
        generatorList.add(new CateringStorePdfGenerator());
        if (fieldDTO.getAttributesOfInspectionUnits().equals(CateringStorePdfGenerator.NAME)) {
            generatorList.add(new RectifyImgPdfGenerator());
        }

        // 威清门街道办事处交通应急巡查台账（餐饮店面）
        generatorList.add(new CateringTrafficPdfGenerator());

        // 威清门街道办事处应急巡查台账（店面）
        generatorList.add(new StorefrontPdfGenerator());
        if (fieldDTO.getAttributesOfInspectionUnits().equals(StorefrontPdfGenerator.NAME)) {
            generatorList.add(new RectifyImgPdfGenerator());
        }

        // 威清门街道办事处应急巡查台账（临摊夜市摊）
        generatorList.add(new NightMarketStallPdfGenerator());
        if (fieldDTO.getAttributesOfInspectionUnits().equals(NightMarketStallPdfGenerator.NAME)) {
            generatorList.add(new RectifyImgPdfGenerator());
        }

        // 威清门街道办事处应急巡查台账（工地装修）
        generatorList.add(new SiteDecorationPdfGenerator());
        if (fieldDTO.getAttributesOfInspectionUnits().equals(SiteDecorationPdfGenerator.NAME)) {
            generatorList.add(new RectifyImgPdfGenerator());
        }

        // 威清门街道办事处应急巡查台账（危房）
        generatorList.add(new DangerousBuildingPdfGenerator());

        // 威清门街道办事处应急巡查台账（单位物管）
        generatorList.add(new UnitPropertyManagementPdfGenerator());
        if (fieldDTO.getAttributesOfInspectionUnits().equals(UnitPropertyManagementPdfGenerator.NAME)) {
            generatorList.add(new RectifyImgPdfGenerator());
        }

        // 威清门街道办事处应急巡查台账（重点场所）
        generatorList.add(new KeyPlacePdfGenerator());
        if (KeyPlacePdfGenerator.NAMES.contains(fieldDTO.getAttributesOfInspectionUnits())) {
            generatorList.add(new RectifyImgPdfGenerator());
        }

        // 威清门街道办事处三合一应急巡查台账(三合一)
        generatorList.add(new ThreeAndOnePdfGenerator());

        // 威清门街道办事处交通应急巡查台账（快递）
        generatorList.add(new ExpressPdfGenerator());
        if (fieldDTO.getAttributesOfInspectionUnits().equals(StorefrontPdfGenerator.NAME) &&
                fieldDTO.getPlaceType().getKey().equals(ExpressPdfGenerator.NAME) &&
                fieldDTO.getWhetherItIsATrafficEmergency()) {
            generatorList.add(new RectifyImgPdfGenerator());
        }

        // 餐饮经营服务场所消防安全巡查台账(上一次)
        generatorList.add(new CateringServiceLastPdfGenerator());

        // 餐饮经营服务场所消防安全巡查台账(本次)
        generatorList.add(new CateringServicePdfGenerator());

        // 瓶装燃气用户安全管理检查表
        generatorList.add(new BottledGasPdfGenerator());

        // 安全生产整改通知书
        generatorList.add(new SafeProductionPdfGenerator());

        return generatorList;
    }

    /**
     * 用户自定义下载pdf文件的名称
     *
     * @param pdfGenerateParam 创建pdf所提供的参数
     * @return 结果
     */
    @Override
    protected String getDownloadFileName(PdfGenerateParam pdfGenerateParam) {
        SafetyCheckDTO fieldDTO = (SafetyCheckDTO) pdfGenerateParam.getAbstractCustomerPdfCreateField();
        String name = fieldDTO.getPlaceName();
        String type = fieldDTO.getAttributesOfInspectionUnits();
        if ("危房".equals(type)) {
            name = fieldDTO.getAddress();
        }
        String fileName = SafetyCheckEnum.SAFETY_INVESTIGATE_RENOVATE.getName();
        fileName = StrFormatter.format("{}{}{}{}", name, fileName, DateUtil.format(new Date(), "yyyyMMdd"), "(" + type + ")");
        return fileName;
    }

    /**
     * 第五张表中的需要的类型，详情见 {@link SqfwFormSummaryConstants}
     *
     * @return 返回数据
     */
    @Override
    public String getSummaryType() {
        return SqfwFormSummaryConstants.safety_check;
    }

    /**
     * 主pdf创建成功之后，再创建其他pdf、发短信
     */
    @Override
    public void afterGeneratePdfSuccess(GeneratorPdfWordResult generateResult) {
        Map<String, Object> bridgeMap = generateResult.getBridgeMap();
        Sqfw_formSummary_new formSummaryNew = (Sqfw_formSummary_new) bridgeMap.get(BasePdfService.forSummaryNewConsName);
        Sqfw_completeflow completeFlow = (Sqfw_completeflow) bridgeMap.get(BasePdfService.completeFlowConsName);

        CompleteFlowPdfParamForController paramForController = new CompleteFlowPdfParamForController();
        CompleteFlowTemplateCodeUpdateDTO completeFlowDataDTO = new CompleteFlowTemplateCodeUpdateDTO();
        completeFlowDataDTO.setFormSummary(formSummaryNew);

        SqfwCompleteFlowUpdateDTO sqfwCompleteFlowUpdateDTO = new SqfwCompleteFlowUpdateDTO();
        BeanUtil.copyProperties(completeFlow, sqfwCompleteFlowUpdateDTO);
        completeFlowDataDTO.setCompleteFlow(sqfwCompleteFlowUpdateDTO);

        paramForController.setCompleteFlowDataDTO(completeFlowDataDTO);
        paramForController.setUserId(formSummaryNew.getCreateBy());

        // 创建其他pdf
        this.createPdf(paramForController);

        //如果是重置，就不需要发短信了
        if (generateResult.getReCreatePdfFlag()) return;

        // 发送短信
        this.sendMsg(formSummaryNew);
    }

    /**
     * 发送短信
     *
     * @param formSummaryNew
     */
    private void sendMsg(Sqfw_formSummary_new formSummaryNew) {
        SafetyCheckDTO dto = JSON.parseObject(formSummaryNew.getParamData(), SafetyCheckDTO.class);

        // 发送短信
        SmsMsgDTO smsMsgDTO = new SmsMsgDTO();
        smsMsgDTO.setPhoneNumberSet(Sets.newHashSet(dto.getOperatorTelephone()));
        String url = DfxyWeChatMPUtils.generatedDfxyMiniProgramUrl("/pages/user-center/safeList");
        if (StringUtils.isNotBlank(url)) {
            String msgContentStr = "您的安全排查整治表可在微信小程序中进行查看:" + url;
            int status = ztSmsService.ztSendSafetyCheckInfoMsg(dto.getOperatorTelephone(), url);
            // 保存短信
            Sqfw_Sms_Msg smsMsg = new Sqfw_Sms_Msg();
            smsMsg.setSummaryId(formSummaryNew.getId());
            smsMsg.setPhone(dto.getOperatorTelephone());
            smsMsg.setUserName(dto.getOperator());
            smsMsg.setAddress(dto.getAddress());
            smsMsg.setName(dto.getPlaceName());
            smsMsg.setCreateDate(new Date());
            smsMsg.setStatus(status == 1 ? "成功" : "失败");
            smsMsg.setMsg(msgContentStr);
            smsMsg.setType(this.getSummaryType());
            smsMsg.setCreateDate(new Date());
            sqfwSmsMsgService.insert(smsMsg);
        }
    }

    /**
     * 创建其他pdf
     *
     * @param paramForController
     */
    private void createPdf(CompleteFlowPdfParamForController paramForController) {
        trafficEmergencyInspectionPdfService.createPdf(paramForController);
        bottledGasUserSafetyManagementPdfService.createPdf(paramForController);
        keyPlacePdfService.createPdf(paramForController);
        emergencyInspectionPdfService.createPdf(paramForController);
        fireSafetyInCateringEstablishmentsPdfService.createPdf(paramForController);
        threeInOneInspectionPdfService.createPdf(paramForController);
    }

    /**
     * 下载sqfw_form_summary_pdf
     *
     * @param config
     * @param sqfwIdList
     * @return
     */
    private ResultOfExcelGenerator downSummaryPdfList(ExcelCreateConfig config, List<String> summaryIds, List<String> sqfwIdList) {
        ResultOfExcelGenerator generateExcelUrlVO = new ResultOfExcelGenerator();
        generateExcelUrlVO.setFileIdentity(config.getFileIdentity());

        int index = Integer.parseInt(config.getFileIdentity());
        String sql;
        if (summaryIds != null) {
            sql = "select url from shequ.sqfw_form_summary_pdf where index = " + index + " and status = '2'" +
                    " and summary_id in " + StrUtil.formatIds(summaryIds);
        } else if (sqfwIdList != null && sqfwIdList.size() > 0) {
            sql = "select url from shequ.sqfw_form_summary_pdf where index = " + index + " and status = '2'" +
                    " and summary_id in (select id from shequ.sqfw_form_summary_new where sqfw_id in " + StrUtil.formatIds(sqfwIdList) + ")";
        } else {
            sql = "select url from shequ.sqfw_form_summary_pdf where index = " + index + " and status = '2'" +
                    " and summary_id in (select id from shequ.sqfw_form_summary_new where create_by = '" + SecurityUtil.getUserId() + "' and " +
                    " type = '"+ getSummaryType() +"')";
        }

        sql += "order by create_date asc";

        List<Sqfw_form_summary_pdf> pdfList = sqfwFormSummaryPdfService.listEntity(Sqls.create(sql));

        if (pdfList != null && pdfList.size() > 0) {
            generateExcelUrlVO.setPassCreateConditionFlag(true);
        } else {
            generateExcelUrlVO.setPassCreateConditionFlag(false);
        }

        // 数据检测
        if (!config.getCreateExcelFileFlag() || pdfList == null || pdfList.size() == 0) {
            return generateExcelUrlVO;
        }

        // 下载pdf
        List<String> urlList = pdfList.stream().map(Sqfw_form_summary_pdf::getUrl).collect(Collectors.toList());
        try {
            String fileName = SafetyCheckEnum.getCompilationName(config.getFileIdentity());
            fileName = StrFormatter.format("{}-{}", fileName, DateUtil.format(new Date(), "yyyyMMdd"));
            String url = CommonFormOfficeUtils.createConvergePdf(urlList, fileName);
            url = (url.startsWith("/")) ? NutzIocUtils.getOssPrefix() + url : url;
            generateExcelUrlVO.setExcelUrl(url);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return generateExcelUrlVO;
    }

    /**
     * 下载sqfw_form_summary_pdf
     *
     * @param config
     * @param summaryPdfList
     * @return
     */
    private ResultOfExcelGenerator downSummaryPdfList(ExcelCreateConfig config, List<Sqfw_form_summary_pdf> summaryPdfList) {
        ResultOfExcelGenerator generateExcelUrlVO = new ResultOfExcelGenerator();
        generateExcelUrlVO.setFileIdentity(config.getFileIdentity());

        List<Sqfw_form_summary_pdf> pdfList = new ArrayList<>();
        for (Sqfw_form_summary_pdf pdf : summaryPdfList) {
            if (Integer.parseInt(config.getFileIdentity()) == pdf.getIndex()) {
                pdfList.add(pdf);
            }
        }

        if (pdfList != null && pdfList.size() > 0) {
            generateExcelUrlVO.setPassCreateConditionFlag(true);
        } else {
            generateExcelUrlVO.setPassCreateConditionFlag(false);
        }

        // 数据检测
        if (!config.getCreateExcelFileFlag() || pdfList == null || pdfList.size() == 0) {
            return generateExcelUrlVO;
        }

        // 下载pdf
        List<String> urlList = pdfList.stream().map(Sqfw_form_summary_pdf::getUrl).collect(Collectors.toList());
        try {
            String fileName = SafetyCheckEnum.getCompilationName(config.getFileIdentity());
            fileName = StrFormatter.format("{}-{}", fileName, DateUtil.format(new Date(), "yyyyMMdd"));
            String url = CommonFormOfficeUtils.createConvergePdf(urlList, fileName);
            url = (url.startsWith("/")) ? NutzIocUtils.getOssPrefix() + url : url;
            generateExcelUrlVO.setExcelUrl(url);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return generateExcelUrlVO;
    }

    /**
     * 加入辖区商铺
     *
     * @param formSummary
     */
    @Override
    protected void beforeInsertForSummary(Sqfw_formSummary_new formSummary) {
        if (StringUtils.isNotBlank(formSummary.getShopsBaseInfoId())) return;

        // 入库商铺
        String paramData = formSummary.getParamData();
        SafetyCheckDTO publicSecurityDTO = JSONObject.toJavaObject(JSONObject.parseObject(paramData), SafetyCheckDTO.class);
        SqfwShopsBaseInfo shopsBaseInfo = new SqfwShopsBaseInfo();

        shopsBaseInfo.setServiceType(SupportBusinessTypeEnum.ENTERPRISE_WARRANTY_SERVE.getCode());
        shopsBaseInfo.setPlaceName(publicSecurityDTO.getPlaceName());
        shopsBaseInfo.setOperator(publicSecurityDTO.getOperator());
        shopsBaseInfo.setOperatorTelephone(publicSecurityDTO.getOperatorTelephone());

        shopsBaseInfo.setAddress(publicSecurityDTO.getAddress());
        shopsBaseInfo.setFillDate(DateUtil.toLocalDateTime(formSummary.getFillDate()));
        Sys_user user = sysUserService.fetch(SecurityUtil.getUserId());
        String detailAddress = String.format("%s%s%s%s%s%s%s", user.getProvince(), user.getCity(), user.getDistrict(),
                user.getCounty(), user.getCommunity(), shopsBaseInfo.getAddress(), shopsBaseInfo.getPlaceName());
        shopsBaseInfo.setDetailAddress(detailAddress);
        shopsBaseInfo.setInspectionSituation(StringUtils.isNotEmpty(shopsBaseInfo.getInspectionSituation()) ? shopsBaseInfo.getInspectionSituation() : formSummary.getInspectionSituation());
        //shopsBaseInfo.setDetailAddress(publicSecurityDTO.getAddress());
        // 检查商铺数据是否存在 存在直接返回
        Cnd cnd = Cnd.NEW();
        SqlExpressionGroup sqlGroup = cnd.where();
        sqlGroup.andEquals(SqfwShopsBaseInfo::getProvince, user.getProvince());
        sqlGroup.andEquals(SqfwShopsBaseInfo::getCity, user.getCity());
        sqlGroup.andEquals(SqfwShopsBaseInfo::getDistrict, user.getDistrict());
        sqlGroup.andEquals(SqfwShopsBaseInfo::getCounty, user.getCounty());
        if (!CommonConstants.DIRECTLY_UNDER.equals(user.getCommunity())) {
            sqlGroup.andEquals(SqfwShopsBaseInfo::getCommunity, user.getCommunity());
        }
        if (StringUtils.isNotEmpty(shopsBaseInfo.getPlaceName())) {
            String placeName = shopsBaseInfo.getPlaceName().trim();
            sqlGroup.andEquals(SqfwShopsBaseInfo::getPlaceName, placeName);
            shopsBaseInfo.setPlaceName(placeName);
        }

        if (StringUtils.isNotEmpty(shopsBaseInfo.getAddress())) {
            String address = shopsBaseInfo.getAddress().trim();
            sqlGroup.andEquals(SqfwShopsBaseInfo::getAddress, address);
            shopsBaseInfo.setAddress(address);
        }
        SqfwShopsBaseInfo s = this.shopsBaseInfoService.fetch(cnd);
        if (s != null) {
            // 不做五级更新
            s.setUpdateDate(LocalDateTime.now())
                    .setAddress(shopsBaseInfo.getAddress())
                    .setOperator(shopsBaseInfo.getOperator())
                    .setOperatorTelephone(shopsBaseInfo.getOperatorTelephone())
                    .setMainBusinessScope(shopsBaseInfo.getMainBusinessScope())
                    .setUpdateId(SecurityUtil.getUserId())
                    .setDeleted(false)
            ;
            if (StringUtils.isBlank(s.getServiceType())) {
                s.setServiceType(SupportBusinessTypeEnum.ENTERPRISE_WARRANTY_SERVE.getCode());
            } else if (!s.getServiceType().contains(SupportBusinessTypeEnum.ENTERPRISE_WARRANTY_SERVE.getCode())) {
                s.setServiceType(s.getServiceType() + "," + SupportBusinessTypeEnum.ENTERPRISE_WARRANTY_SERVE.getCode());
            }
            //原来是停业，巡检后改变状态
            if (SqfwFormSummaryFieldEnum.CHECK_STATUS_CLOSED.getCode().equals(s.getShopStatus())) {
                s.setShopStatus(formSummary.getCheckStatus());
            }
            this.shopsBaseInfoService.updateIgnoreNull(s);
            formSummary.setShopsBaseInfoId(s.getId());
        } else {
            // 不存在 则新增
            shopsBaseInfo.setCreateDate(LocalDateTime.now())
                    .setUpdateDate(LocalDateTime.now())
                    .setCreateId(SecurityUtil.getUserId())
                    .setUpdateId(SecurityUtil.getUserId())
                    .setDeleted(false)
                    .setProvince(user.getProvince())
                    .setCity(user.getCity())
                    .setCounty(user.getCounty())
                    .setCommunity(user.getCommunity())
                    .setDistrict(user.getDistrict())
                    .setShopStatus(formSummary.getCheckStatus())
            ;
            this.shopsBaseInfoService.insert(shopsBaseInfo);
            formSummary.setShopsBaseInfoId(shopsBaseInfo.getId());
        }
    }
}
